package com.shrcl.engineerprocess.domain.impl;

import com.google.common.base.Objects;
import com.shrcl.engineerprocess.domain.CorpWeChatUser;
import com.shrcl.engineerprocess.domain.CorpWeChatUserDAO;
import com.shrcl.engineerprocess.domain.Engineer;
import com.shrcl.engineerprocess.domain.EngineerCapability;
import com.shrcl.engineerprocess.domain.EngineerCertification;
import com.shrcl.engineerprocess.domain.EngineerLevel;
import com.shrcl.engineerprocess.domain.EngineerMonthlyCost;
import com.shrcl.engineerprocess.domain.EngineerNotifyReceiver;
import com.shrcl.engineerprocess.domain.EngineerStatus;
import com.shrcl.engineerprocess.domain.events.CorpWeChatUserEventsManager;
import com.shrcl.engineerprocess.domain.impl.EngineerCapabilityImpl;
import com.shrcl.engineerprocess.domain.impl.EngineerCertificationImpl;
import com.shrcl.engineerprocess.domain.impl.EngineerLevelImpl;
import com.shrcl.engineerprocess.domain.impl.EngineerMonthlyCostImpl;
import com.shrcl.engineerprocess.domain.proxy.EngineerProxy;
import com.shrct.businessprocess.organization.RCEmployee;
import com.shrct.businessprocess.organization.impl.RCEmployeeImpl;
import edu.fudan.langlab.domain.security.User;
import edu.fudan.langlab.domain.statemachine.ModelObjectLogService;
import edu.fudan.mylang.pf.BaseModelObject;
import edu.fudan.mylang.pf.IGenericQuery;
import edu.fudan.mylang.pf.IObjectFactory;
import edu.fudan.mylang.pf.ISystemDateTimeService;
import edu.fudan.mylang.utils.DateUtil;
import edu.fudan.mylang.utils.DateUtil.Month;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import org.eclipse.xtext.xbase.lib.Functions.Function1;
import org.eclipse.xtext.xbase.lib.Functions.Function2;
import org.eclipse.xtext.xbase.lib.InputOutput;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.ListExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.hibernate.annotations.DiscriminatorOptions;
import org.springframework.beans.factory.BeanFactory;

@Entity
@DiscriminatorValue("ENGINEER_TYPE")
@DiscriminatorOptions(force = true)
@DiscriminatorColumn(length = 64)
@Table(name = "engineer")
public class EngineerImpl extends BaseModelObject implements Engineer {
  public EngineerImpl() {
    super();
  }
  
  private EngineerStatus Status;
  
  public EngineerStatus getStatus() {
    return this.Status;
  }
  
  private ModelObjectLogService getModelObjectLogService() {
    return getBeanFactory().getBean(ModelObjectLogService.class);
  }
  
  private void _start() {
    
    Status=EngineerStatus.created;
  }
  
  public void start() {
    if(Status==null){
    	_start();
    	getModelObjectLogService().createLog(this,"Status","Start");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireStarted(this);					
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("allready started");
    }
  }
  
  private void _leave() {
    
    Status=EngineerStatus.quited;
  }
  
  public void leave() {
    if(Status==EngineerStatus.created){
    	_leave();
    	getModelObjectLogService().createLog(this,"Status","leave");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireLeave(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private EngineerCapability _addCapability(final Procedure1<? super EngineerCapability> init) {
    EngineerCapability _createAndAddtoCapabilities = this.createAndAddtoCapabilities();
    final Procedure1<EngineerCapability> _function = new Procedure1<EngineerCapability>() {
        public void apply(final EngineerCapability it) {
          init.apply(it);
        }
      };
    EngineerCapability _doubleArrow = ObjectExtensions.<EngineerCapability>operator_doubleArrow(_createAndAddtoCapabilities, _function);
    return _doubleArrow;
  }
  
  public EngineerCapability addCapability(final Procedure1<? super EngineerCapability> init) {
    if(Status==EngineerStatus.created){
    	EngineerCapability result = _addCapability(init);
    	getModelObjectLogService().createLog(this,"Status","addCapability");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireAddCapability(this,init);
    	return result;						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("Status.name()");
    }
  }
  
  private void _removeCapability(final EngineerCapability engineerCapability) {
    
    this.removeFromCapabilities(engineerCapability);
  }
  
  public void removeCapability(final EngineerCapability engineerCapability) {
    if(Status==EngineerStatus.created){
    	_removeCapability(engineerCapability);
    	getModelObjectLogService().createLog(this,"Status","removeCapability");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireRemoveCapability(this,engineerCapability);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private EngineerCertification _addCertification(final Procedure1<? super EngineerCertification> init) {
    EngineerCertification _createAndAddtoCertifications = this.createAndAddtoCertifications();
    final Procedure1<EngineerCertification> _function = new Procedure1<EngineerCertification>() {
        public void apply(final EngineerCertification it) {
          it.start();
          it.update(init);
        }
      };
    EngineerCertification _doubleArrow = ObjectExtensions.<EngineerCertification>operator_doubleArrow(_createAndAddtoCertifications, _function);
    return _doubleArrow;
  }
  
  public EngineerCertification addCertification(final Procedure1<? super EngineerCertification> init) {
    if(Status==EngineerStatus.created){
    	EngineerCertification result = _addCertification(init);
    	getModelObjectLogService().createLog(this,"Status","addCertification");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireAddCertification(this,init);
    	return result;						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("Status.name()");
    }
  }
  
  private void _removeCertification(final EngineerCertification engineerCertification) {
    
    this.removeFromCertifications(engineerCertification);
  }
  
  public void removeCertification(final EngineerCertification engineerCertification) {
    if(Status==EngineerStatus.created){
    	_removeCertification(engineerCertification);
    	getModelObjectLogService().createLog(this,"Status","removeCertification");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireRemoveCertification(this,engineerCertification);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private EngineerMonthlyCost _addMonthlyCost(final Procedure1<? super EngineerMonthlyCost> init) {
    EngineerMonthlyCost _createAndAddtoEngineerMonthlyCost = this.createAndAddtoEngineerMonthlyCost();
    final Procedure1<EngineerMonthlyCost> _function = new Procedure1<EngineerMonthlyCost>() {
        public void apply(final EngineerMonthlyCost it) {
          init.apply(it);
          it.start();
          final Procedure1<EngineerMonthlyCost> _function = new Procedure1<EngineerMonthlyCost>() {
              public void apply(final EngineerMonthlyCost amc) {
                final Procedure1<EngineerLevel> _function = new Procedure1<EngineerLevel>() {
                    public void apply(final EngineerLevel it) {
                      amc.addtoLevels(it);
                    }
                  };
                IterableExtensions.<EngineerLevel>forEach(EngineerImpl.this.levels, _function);
              }
            };
          it.updateCost(_function);
        }
      };
    EngineerMonthlyCost _doubleArrow = ObjectExtensions.<EngineerMonthlyCost>operator_doubleArrow(_createAndAddtoEngineerMonthlyCost, _function);
    return _doubleArrow;
  }
  
  public EngineerMonthlyCost addMonthlyCost(final Procedure1<? super EngineerMonthlyCost> init) {
    if(Status==EngineerStatus.created){
    	EngineerMonthlyCost result = _addMonthlyCost(init);
    	getModelObjectLogService().createLog(this,"Status","addMonthlyCost");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireAddMonthlyCost(this,init);
    	return result;						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException("Status.name()");
    }
  }
  
  private void _removeMonthlyCost(final EngineerMonthlyCost monthlyCost) {
    
    this.removeFromEngineerMonthlyCost(monthlyCost);
  }
  
  public void removeMonthlyCost(final EngineerMonthlyCost monthlyCost) {
    if(Status==EngineerStatus.created){
    	_removeMonthlyCost(monthlyCost);
    	getModelObjectLogService().createLog(this,"Status","removeMonthlyCost");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireRemoveMonthlyCost(this,monthlyCost);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _monthlyCostTimer() {
    
    BeanFactory _beanFactory = this.getBeanFactory();
    final ISystemDateTimeService dateTimeService = _beanFactory.<ISystemDateTimeService>getBean(ISystemDateTimeService.class);
    InputOutput.<String>println("====>Copy last month salary");
    EngineerMonthlyCost _currentMonthlyCost = this.getCurrentMonthlyCost();
    final Double curcost = _currentMonthlyCost.getCost();
    final Procedure1<EngineerMonthlyCost> _function = new Procedure1<EngineerMonthlyCost>() {
        public void apply(final EngineerMonthlyCost amc) {
          amc.setCost(curcost);
          Date _day = dateTimeService.today();
          Date _trim2Month = DateUtil.trim2Month(_day);
          amc.setMonth(_trim2Month);
        }
      };
    this.addMonthlyCost(_function);
  }
  
  public void monthlyCostTimer() {
    if(Status==EngineerStatus.created){
    	_monthlyCostTimer();
    	getModelObjectLogService().createLog(this,"Status","monthlyCostTimer");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireMonthlyCostTimer(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _updateEngineerLevels(final Collection<EngineerLevel> levels) {
    
    this.removeAllLevels();
    final Procedure1<EngineerLevel> _function = new Procedure1<EngineerLevel>() {
        public void apply(final EngineerLevel it) {
          EngineerImpl.this.addtoLevels(it);
        }
      };
    IterableExtensions.<EngineerLevel>forEach(levels, _function);
    EngineerMonthlyCost _currentMonthlyCost = this.getCurrentMonthlyCost();
    final Procedure1<EngineerMonthlyCost> _function_1 = new Procedure1<EngineerMonthlyCost>() {
        public void apply(final EngineerMonthlyCost amc) {
          amc.removeAllLevels();
          final Procedure1<EngineerLevel> _function = new Procedure1<EngineerLevel>() {
              public void apply(final EngineerLevel it) {
                amc.addtoLevels(it);
              }
            };
          IterableExtensions.<EngineerLevel>forEach(levels, _function);
        }
      };
    if (_currentMonthlyCost!=null) _currentMonthlyCost.updateCost(_function_1);
  }
  
  public void updateEngineerLevels(final Collection<EngineerLevel> levels) {
    if(Status==EngineerStatus.created){
    	_updateEngineerLevels(levels);
    	getModelObjectLogService().createLog(this,"Status","updateEngineerLevels");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireUpdateEngineerLevels(this,levels);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  private void _reactive() {
    
    Status=EngineerStatus.created;
  }
  
  public void reactive() {
    if(Status==EngineerStatus.quited){
    	_reactive();
    	getModelObjectLogService().createLog(this,"Status","reactive");
    	getBeanFactory().getBean(com.shrcl.engineerprocess.domain.events.EngineerEventsManager.class).fireReactive(this);						
    }else{
    	throw new edu.fudan.langlab.domain.statemachine.InvalidStateException(Status.name());
    }
  }
  
  public Boolean isCreated() {
    return com.shrcl.engineerprocess.domain.EngineerStatus.created==Status;
  }
  
  public Boolean isQuited() {
    return com.shrcl.engineerprocess.domain.EngineerStatus.quited==Status;
  }
  
  @JoinColumn(name = "employee_id")
  @ManyToOne(targetEntity = RCEmployeeImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
  private RCEmployee employee;
  
  public RCEmployee getEmployee() {
    return this.employee;
  }
  
  public Engineer setEmployee(final RCEmployee employee) {
    this.employee = employee;
    return this;			
    
  }
  
  private String code;
  
  public String getCode() {
    return this.code;
  }
  
  public Engineer setCode(final String code) {
    this.code = code;
    return this;			
    
  }
  
  private String name;
  
  public String getName() {
    return this.name;
  }
  
  public Engineer setName(final String name) {
    this.name = name;
    return this;			
    
  }
  
  private String simplePy;
  
  public String getSimplePy() {
    return this.simplePy;
  }
  
  public Engineer setSimplePy(final String simplePy) {
    this.simplePy = simplePy;
    return this;			
    
  }
  
  private String email;
  
  public String getEmail() {
    return this.email;
  }
  
  public Engineer setEmail(final String email) {
    this.email = email;
    return this;			
    
  }
  
  private Double salary;
  
  public Double getSalary() {
    return this.salary;
  }
  
  public Engineer setSalary(final Double salary) {
    this.salary = salary;
    return this;			
    
  }
  
  @ManyToMany(targetEntity = EngineerLevelImpl.class)
  @JoinTable(name = "m2m_engineer_levels", joinColumns = @JoinColumn(name = "engineer_id") , inverseJoinColumns = @JoinColumn(name = "engineerLevel_inv_id") )
  private Collection<EngineerLevel> levels = new java.util.ArrayList<com.shrcl.engineerprocess.domain.EngineerLevel>();;
  
  public Collection<EngineerLevel> getLevels() {
    return this.levels;
  }
  
  public Engineer setLevels(final Iterable<EngineerLevel> levels) {
    removeAllLevels();
    for(EngineerLevel ca : levels){
    	addtoLevels(ca);
    }
    return this;		
    
  }
  
  public Engineer addtoLevels(final EngineerLevel engineerLevel) {
    this.levels.add(engineerLevel);
    return this;
    
  }
  
  public Engineer removeAllLevels() {
    this.levels.clear();
    return this;	
    
  }
  
  public Engineer removeFromLevels(final EngineerLevel engineerLevel) {
    this.levels.remove(engineerLevel);
    return this;
    
  }
  
  @OneToMany(targetEntity = EngineerCertificationImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "engineer")
  private Collection<EngineerCertification> certifications = new java.util.ArrayList<com.shrcl.engineerprocess.domain.EngineerCertification>();;
  
  public Collection<EngineerCertification> getCertifications() {
    return this.certifications;
  }
  
  public EngineerCertification createAndAddtoCertifications() {
    getCertifications().size();
    com.shrcl.engineerprocess.domain.EngineerCertification engineerCertification = new com.shrcl.engineerprocess.domain.impl.EngineerCertificationImpl(this);
    getObjectFactory().create(engineerCertification);
    getCertifications().add(engineerCertification);
    return engineerCertification;
    
  }
  
  public EngineerCertification createAndAddtoCertifications(final Procedure1<EngineerCertification> updater) {
    getCertifications().size();
    com.shrcl.engineerprocess.domain.EngineerCertification engineerCertification = new com.shrcl.engineerprocess.domain.impl.EngineerCertificationImpl(this);
    getObjectFactory().create(engineerCertification);
    getCertifications().add(engineerCertification);
    return engineerCertification;
    
  }
  
  public Engineer removeAllCertifications() {
    for(EngineerCertification obj : this.certifications){
    	getObjectFactory().delete(obj);
    }
    this.certifications.clear();
    return this;	
    
  }
  
  public Engineer removeFromCertifications(final EngineerCertification engineerCertification) {
    this.certifications.remove(engineerCertification);
    getObjectFactory().delete(engineerCertification);
    return this;
    
  }
  
  @OneToMany(targetEntity = EngineerCapabilityImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "engineer")
  private Collection<EngineerCapability> capabilities = new java.util.ArrayList<com.shrcl.engineerprocess.domain.EngineerCapability>();;
  
  public Collection<EngineerCapability> getCapabilities() {
    return this.capabilities;
  }
  
  public EngineerCapability createAndAddtoCapabilities() {
    getCapabilities().size();
    com.shrcl.engineerprocess.domain.EngineerCapability engineerCapability = new com.shrcl.engineerprocess.domain.impl.EngineerCapabilityImpl(this);
    getObjectFactory().create(engineerCapability);
    getCapabilities().add(engineerCapability);
    return engineerCapability;
    
  }
  
  public EngineerCapability createAndAddtoCapabilities(final Procedure1<EngineerCapability> updater) {
    getCapabilities().size();
    com.shrcl.engineerprocess.domain.EngineerCapability engineerCapability = new com.shrcl.engineerprocess.domain.impl.EngineerCapabilityImpl(this);
    getObjectFactory().create(engineerCapability);
    getCapabilities().add(engineerCapability);
    return engineerCapability;
    
  }
  
  public Engineer removeAllCapabilities() {
    for(EngineerCapability obj : this.capabilities){
    	getObjectFactory().delete(obj);
    }
    this.capabilities.clear();
    return this;	
    
  }
  
  public Engineer removeFromCapabilities(final EngineerCapability engineerCapability) {
    this.capabilities.remove(engineerCapability);
    getObjectFactory().delete(engineerCapability);
    return this;
    
  }
  
  @OneToMany(targetEntity = EngineerMonthlyCostImpl.class, cascade = { CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE }, mappedBy = "engineer")
  private Collection<EngineerMonthlyCost> engineerMonthlyCost = new java.util.ArrayList<com.shrcl.engineerprocess.domain.EngineerMonthlyCost>();;
  
  public Collection<EngineerMonthlyCost> getEngineerMonthlyCost() {
    return this.engineerMonthlyCost;
  }
  
  public EngineerMonthlyCost createAndAddtoEngineerMonthlyCost() {
    getEngineerMonthlyCost().size();
    com.shrcl.engineerprocess.domain.EngineerMonthlyCost engineerMonthlyCost = new com.shrcl.engineerprocess.domain.impl.EngineerMonthlyCostImpl(this);
    getObjectFactory().create(engineerMonthlyCost);
    getEngineerMonthlyCost().add(engineerMonthlyCost);
    return engineerMonthlyCost;
    
  }
  
  public EngineerMonthlyCost createAndAddtoEngineerMonthlyCost(final Procedure1<EngineerMonthlyCost> updater) {
    getEngineerMonthlyCost().size();
    com.shrcl.engineerprocess.domain.EngineerMonthlyCost engineerMonthlyCost = new com.shrcl.engineerprocess.domain.impl.EngineerMonthlyCostImpl(this);
    getObjectFactory().create(engineerMonthlyCost);
    getEngineerMonthlyCost().add(engineerMonthlyCost);
    return engineerMonthlyCost;
    
  }
  
  public Engineer removeAllEngineerMonthlyCost() {
    for(EngineerMonthlyCost obj : this.engineerMonthlyCost){
    	getObjectFactory().delete(obj);
    }
    this.engineerMonthlyCost.clear();
    return this;	
    
  }
  
  public Engineer removeFromEngineerMonthlyCost(final EngineerMonthlyCost engineerMonthlyCost) {
    this.engineerMonthlyCost.remove(engineerMonthlyCost);
    getObjectFactory().delete(engineerMonthlyCost);
    return this;
    
  }
  
  private Boolean isRemoved;
  
  public Boolean getIsRemoved() {
    return this.isRemoved;
  }
  
  public Engineer setIsRemoved(final Boolean isRemoved) {
    this.isRemoved = isRemoved;
    return this;			
    
  }
  
  public Integer getCurrentLevel() {
    final Function1<EngineerCapability,Integer> _function = new Function1<EngineerCapability,Integer>() {
        public Integer apply(final EngineerCapability it) {
          Integer _currentLevel = it.getCurrentLevel();
          return _currentLevel;
        }
      };
    Iterable<Integer> _map = IterableExtensions.<EngineerCapability, Integer>map(this.capabilities, _function);
    final Function2<Integer,Integer,Integer> _function_1 = new Function2<Integer,Integer,Integer>() {
        public Integer apply(final Integer a, final Integer b) {
          int _plus = ((a).intValue() + (b).intValue());
          return Integer.valueOf(_plus);
        }
      };
    Integer _reduce = IterableExtensions.<Integer>reduce(_map, _function_1);
    return _reduce;
  }
  
  public String getNameField() {
    return "name";
  }
  
  public Integer getExpectedLevel() {
    final Function1<EngineerCapability,Integer> _function = new Function1<EngineerCapability,Integer>() {
        public Integer apply(final EngineerCapability it) {
          Integer _expectedLevel = it.getExpectedLevel();
          return _expectedLevel;
        }
      };
    Iterable<Integer> _map = IterableExtensions.<EngineerCapability, Integer>map(this.capabilities, _function);
    final Function2<Integer,Integer,Integer> _function_1 = new Function2<Integer,Integer,Integer>() {
        public Integer apply(final Integer a, final Integer b) {
          int _plus = ((a).intValue() + (b).intValue());
          return Integer.valueOf(_plus);
        }
      };
    Integer _reduce = IterableExtensions.<Integer>reduce(_map, _function_1);
    return _reduce;
  }
  
  public String getEntityName() {
    return this.name;
  }
  
  public Boolean monthCostExisting(final Date m) {
    final Function1<EngineerMonthlyCost,Boolean> _function = new Function1<EngineerMonthlyCost,Boolean>() {
        public Boolean apply(final EngineerMonthlyCost it) {
          boolean _and = false;
          Date _month = it.getMonth();
          Month _month_1 = DateUtil.getMonth(_month);
          int _year = _month_1.getYear();
          Month _month_2 = DateUtil.getMonth(m);
          int _year_1 = _month_2.getYear();
          boolean _equals = (_year == _year_1);
          if (!_equals) {
            _and = false;
          } else {
            Date _month_3 = it.getMonth();
            Month _month_4 = DateUtil.getMonth(_month_3);
            int _month_5 = _month_4.getMonth();
            Month _month_6 = DateUtil.getMonth(m);
            int _month_7 = _month_6.getMonth();
            boolean _equals_1 = (_month_5 == _month_7);
            _and = (_equals && _equals_1);
          }
          return Boolean.valueOf(_and);
        }
      };
    Iterable<EngineerMonthlyCost> _filter = IterableExtensions.<EngineerMonthlyCost>filter(this.engineerMonthlyCost, _function);
    int _size = IterableExtensions.size(_filter);
    boolean _greaterEqualsThan = (_size >= 2);
    return Boolean.valueOf(_greaterEqualsThan);
  }
  
  public CorpWeChatUser asActiveCorpWechatUser() {
    IGenericQuery<CorpWeChatUser> query=getObjectFactory().createGenericQuery(CorpWeChatUser.class,"select e from com.shrcl.engineerprocess.domain.impl.CorpWeChatUserImpl as e   where (((e.engineer) = (:this)) and ((e.excluded) = (false))) and  e.active = 1      ").setParameter("this",this);
    CorpWeChatUser _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public EngineerNotifyReceiver asNotifyReceiver() {
    IGenericQuery<EngineerNotifyReceiver> query=getObjectFactory().createGenericQuery(EngineerNotifyReceiver.class,"select e from com.shrcl.engineerprocess.domain.impl.EngineerNotifyReceiverImpl as e   where ((e.engineer) = (:this)) and  e.active = 1      ").setParameter("this",this);
    EngineerNotifyReceiver _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public CorpWeChatUser getWechatUser() {
    IGenericQuery<CorpWeChatUser> query=getObjectFactory().createGenericQuery(CorpWeChatUser.class,"select e from com.shrcl.engineerprocess.domain.impl.CorpWeChatUserImpl as e   where ((e.engineer) = (:this)) and  e.active = 1      ").setParameter("this",this);
    CorpWeChatUser _uniqueResult = query.uniqueResult();
    return _uniqueResult;
  }
  
  public User asUser() {
    IGenericQuery<RCEmployee> query=getObjectFactory().createGenericQuery(RCEmployee.class,"select e from com.shrct.businessprocess.organization.impl.RCEmployeeImpl as e   where ((e) = (:)) and  e.active = 1      ").setParameter("null",null);
    RCEmployee _uniqueResult = query.uniqueResult();
    User _asUser = _uniqueResult.asUser();
    return _asUser;
  }
  
  public CorpWeChatUser registerCorpWeChatUser(final String wechatuserid) {
    CorpWeChatUser _xblockexpression = null;
    {
      BeanFactory _beanFactory = this.getBeanFactory();
      final CorpWeChatUserEventsManager wechatEvents = _beanFactory.<CorpWeChatUserEventsManager>getBean(CorpWeChatUserEventsManager.class);
      IGenericQuery<CorpWeChatUser> query=getObjectFactory().createGenericQuery(CorpWeChatUser.class,"select e from com.shrcl.engineerprocess.domain.impl.CorpWeChatUserImpl as e   where (((e.wechatuserid) = (:wechatuserid)) and ((e.engineer) = (:this))) and  e.active = 1      ").setParameter("wechatuserid",wechatuserid).setParameter("this",this);
      final CorpWeChatUser u = query.uniqueResult();
      CorpWeChatUser _xifexpression = null;
      boolean _notEquals = (!Objects.equal(u, null));
      if (_notEquals) {
        CorpWeChatUser _xblockexpression_1 = null;
        {
          u.setExcluded(Boolean.valueOf(false));
          Date _now = DateUtil.now();
          u.setRegisterDate(_now);
          _xblockexpression_1 = (u);
        }
        _xifexpression = _xblockexpression_1;
      } else {
        CorpWeChatUser _xblockexpression_2 = null;
        {
          BeanFactory _beanFactory_1 = this.getBeanFactory();
          final CorpWeChatUserDAO dao = _beanFactory_1.<CorpWeChatUserDAO>getBean(CorpWeChatUserDAO.class);
          final Procedure1<CorpWeChatUser> _function = new Procedure1<CorpWeChatUser>() {
              public void apply(final CorpWeChatUser it) {
                it.setEngineer(EngineerImpl.this);
                it.setWechatid(wechatuserid);
                it.setWechatuserid(wechatuserid);
                Date _now = DateUtil.now();
                it.setRegisterDate(_now);
                it.setExcluded(Boolean.valueOf(false));
                wechatEvents.fireCreated(it);
              }
            };
          CorpWeChatUser _create = dao.create(_function);
          _xblockexpression_2 = (_create);
        }
        _xifexpression = _xblockexpression_2;
      }
      _xblockexpression = (_xifexpression);
    }
    return _xblockexpression;
  }
  
  public void unregisterCorpWeChatUser(final String wechatuserid) {
    IGenericQuery<CorpWeChatUser> query=getObjectFactory().createGenericQuery(CorpWeChatUser.class,"select e from com.shrcl.engineerprocess.domain.impl.CorpWeChatUserImpl as e   where (((e.engineer) = (:this)) and ((e.wechatuserid) = (:wechatuserid))) and  e.active = 1      ").setParameter("this",this).setParameter("wechatuserid",wechatuserid);
    Collection<CorpWeChatUser> _list = query.list();
    final Procedure1<CorpWeChatUser> _function = new Procedure1<CorpWeChatUser>() {
        public void apply(final CorpWeChatUser it) {
          it.setExcluded(Boolean.valueOf(true));
        }
      };
    IterableExtensions.<CorpWeChatUser>forEach(_list, _function);
  }
  
  public Boolean isEngineerLevel(final EngineerLevel engineerLevel) {
    final Function1<EngineerLevel,Boolean> _function = new Function1<EngineerLevel,Boolean>() {
        public Boolean apply(final EngineerLevel it) {
          boolean _equals = Objects.equal(it, engineerLevel);
          return Boolean.valueOf(_equals);
        }
      };
    EngineerLevel _findFirst = this.levels==null?(EngineerLevel)null:IterableExtensions.<EngineerLevel>findFirst(this.levels, _function);
    boolean _notEquals = (!Objects.equal(_findFirst, null));
    return Boolean.valueOf(_notEquals);
  }
  
  public Double getCostByMonth(final Date mon) {
    final Function1<EngineerMonthlyCost,Boolean> _function = new Function1<EngineerMonthlyCost,Boolean>() {
        public Boolean apply(final EngineerMonthlyCost it) {
          Date _month = it.getMonth();
          Date _trim2Month = DateUtil.trim2Month(_month);
          Date _trim2Month_1 = DateUtil.trim2Month(mon);
          boolean _equals = Objects.equal(_trim2Month, _trim2Month_1);
          return Boolean.valueOf(_equals);
        }
      };
    EngineerMonthlyCost _findFirst = IterableExtensions.<EngineerMonthlyCost>findFirst(this.engineerMonthlyCost, _function);
    Double _cost = _findFirst==null?(Double)null:_findFirst.getCost();
    return _cost;
  }
  
  public EngineerMonthlyCost getCurrentMonthlyCost() {
    final Function1<EngineerMonthlyCost,Boolean> _function = new Function1<EngineerMonthlyCost,Boolean>() {
        public Boolean apply(final EngineerMonthlyCost it) {
          Date _month = it.getMonth();
          boolean _notEquals = (!Objects.equal(_month, null));
          return Boolean.valueOf(_notEquals);
        }
      };
    Iterable<EngineerMonthlyCost> _filter = IterableExtensions.<EngineerMonthlyCost>filter(this.engineerMonthlyCost, _function);
    final Function1<EngineerMonthlyCost,Date> _function_1 = new Function1<EngineerMonthlyCost,Date>() {
        public Date apply(final EngineerMonthlyCost it) {
          Date _month = it.getMonth();
          Date _trim2Month = DateUtil.trim2Month(_month);
          return _trim2Month;
        }
      };
    List<EngineerMonthlyCost> _sortBy = IterableExtensions.<EngineerMonthlyCost, Date>sortBy(_filter, _function_1);
    List<EngineerMonthlyCost> _reverse = ListExtensions.<EngineerMonthlyCost>reverse(_sortBy);
    EngineerMonthlyCost _head = IterableExtensions.<EngineerMonthlyCost>head(_reverse);
    return _head;
  }
  
  public Collection<EngineerLevel> getNewestMonthlyCostLevels() {
    EngineerMonthlyCost _currentMonthlyCost = this.getCurrentMonthlyCost();
    Collection<EngineerLevel> _levels = _currentMonthlyCost==null?(Collection<EngineerLevel>)null:_currentMonthlyCost.getLevels();
    return _levels;
  }
  
  public static Engineer create(final IObjectFactory objectFactory) {
    com.shrcl.engineerprocess.domain.Engineer engineer = new com.shrcl.engineerprocess.domain.impl.EngineerImpl(
    );
    objectFactory.create(engineer);
    return engineer;			
    
  }
  
  public static Engineer createEngineerImpl(final IObjectFactory objectFactory, final Procedure1<Engineer> init) {
    com.shrcl.engineerprocess.domain.Engineer engineer = new com.shrcl.engineerprocess.domain.impl.EngineerImpl(
    );
    objectFactory.create(engineer);
    init.apply(engineer);
    
    return engineer;			
    
  }
  
  public EngineerProxy toProxy() {
    com.shrcl.engineerprocess.domain.proxy.EngineerProxy proxy = new com.shrcl.engineerprocess.domain.proxy.EngineerProxy();
    proxy.setId(this.getId());
    if(this instanceof edu.fudan.mylang.pf.INamedModelObject){
    	proxy.setName(((edu.fudan.mylang.pf.INamedModelObject)this).getEntityName());
    }
    proxy.setStatus(this.getStatus().name());
    return proxy;
    
  }
}
